import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

public class Cover {
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				CoverFrame frame = new CoverFrame();
				frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
				frame.setVisible(true);
				frame.addWindowListener(new WindowAdapter(){  
					@Override  
					public void windowClosing(WindowEvent e) {  
						super.windowClosing(e);  
						frame.writeCfg();
						System.out.println("window is closed!");  
						System.exit(0);
					}  
				}); 
			}
		});
	}
}

class CoverFrame extends JFrame {
	private Point point = new Point(0, 0);
	private JPopupMenu popupMenu = new JPopupMenu();
	private Color color = new Color(0, 0, 0, 200);
	private boolean onTop = true;
	private CfgManager cfgManager = new CfgManager();
	private Rectangle bounds = null;


	public CoverFrame() {
		setAlwaysOnTop(onTop);
		setUndecorated(true);  
		readCfg();
		setBackground(color);
		if (bounds == null) {
			setSize(600, 100);
			setLocationByPlatform(true);
		} else {
			validateBounds();
			setBounds(bounds);
		}


		getContentPane().setBackground(color);
		CoverFrame that = this;


		// set up popup menus
		JMenuItem closeItem = new JMenuItem("Close");
		closeItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				// make sure close event is catched
				WindowEvent wev = new WindowEvent(that,
						WindowEvent.WINDOW_CLOSING);
				Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
				dispose(); // close window
			}
		});
		popupMenu.add(closeItem);

		JMenuItem pickItem = new JMenuItem("Pick Color");
		pickItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				Color newColor;
				setAlwaysOnTop(false);
				newColor = JColorChooser.showDialog(null, "pick your color",
					   	color);
				setAlwaysOnTop(onTop);
				if(newColor != null) {
					color = newColor;
					setBackground(color);
					getContentPane().setBackground(color);
					repaint();
				}
			}
		});
		popupMenu.add(pickItem);

		JMenuItem topItem = new JCheckBoxMenuItem("Always On Top", true);
		topItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				onTop = !onTop;
				setAlwaysOnTop(onTop);
			}
		});
		popupMenu.add(topItem);

		JMenuItem aboutItem = new JMenuItem("About");
		aboutItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				 JOptionPane.showMessageDialog(that,  //消息对话框依赖的组件
						 "Version:0.3\nDeveloper:William Zheng\nEmail:williamzheng2089@sina.com",//要显示的消息
						 "About", JOptionPane.INFORMATION_MESSAGE);
			}
		});
		popupMenu.add(aboutItem);

		// implement drag function
		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent event) {
				// record the point where you begin to drag
				point = event.getPoint();
				popupEvent(event);
			}
			public void mouseReleased(MouseEvent event) {
				popupEvent(event);
			}

			private void popupEvent(MouseEvent event) {
				if (event.isPopupTrigger()) {
					popupMenu.show(event.getComponent(), event.getX(),
							event.getY());
				}
			}

		} );

		addMouseMotionListener(new MouseMotionListener() {
			private boolean top = false;
			private boolean down = false;
			private boolean left = false;
			private boolean right = false;
			final private int GAP = 3;

			public void mouseMoved(MouseEvent event) {
				int width = getWidth();
				int height = getHeight();
				int x = event.getX();
				int y = event.getY();

				top = false;
				down = false;
				left = false;
				right = false;
				if (Math.abs(y) <= GAP) {
					top = true;
				} else if (Math.abs(y-height) <=GAP) {
					down = true;
				}

				if (Math.abs(x) <= GAP) {
					left = true;
				} else if (Math.abs(x-width) <=GAP) {
					right = true;
				}

				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
				if (top || down)
					setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
				if (left || right)
					setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
				if ((left && top) || (right && down))
					setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
				if ((right && top) || (left && down))
					setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
			}

			public void mouseDragged(MouseEvent event) {
				bounds = getBounds();
				if (!(top || down || left || right)) {
					// drag not resize
					Point absPoint = event.getLocationOnScreen();
					// set the location of window relate to where you click
					absPoint.translate(-(int)point.getX(),
							-(int)point.getY());
					setLocation(absPoint);
				} else {
					//resize
					if (top) {
						bounds.setLocation((int)bounds.getX(), (int)bounds.getY() + event.getY());
						bounds.setSize((int)bounds.getWidth(), (int)bounds.getHeight() - event.getY());
					}
					if (down) {
						bounds.setSize((int)bounds.getWidth(), event.getY());
					}
					if (left) {
						bounds.setLocation((int)bounds.getX() + event.getX(), (int)bounds.getY());
						bounds.setSize((int)bounds.getWidth() - event.getX(), (int)bounds.getHeight());
					}
					if (right) {
						bounds.setSize(event.getX(),(int)bounds.getHeight());
					}
					validateBounds();
					setBounds(bounds);
				}
			}
		} );
	}

	public void readCfg() {
		cfgManager.read();
		color = cfgManager.getColor();
		bounds = cfgManager.getRectangle();
	}

	public void writeCfg() {
		cfgManager.setRectangle(getBounds());
		cfgManager.setColor(color);
		cfgManager.write();

	};

	private void validateBounds() {
		if(bounds.getWidth() <= 1) {
			bounds.setSize(5, (int)bounds.getHeight());
		}
		if(bounds.getHeight() <= 1) {
			bounds.setSize((int)bounds.getWidth(), 5);
		}
	}

}

class CfgManager {
	private Color color;
	private Rectangle rect;

	public CfgManager() {
		color = new Color(200, 50, 100, 200);
		rect = null;
	}

	public void read() {
		try {
			File file = new File("cover.cfg");  
            if (!file.exists()) {  
				return;
			}
			Scanner scanner = new Scanner(file);
			int[] rgba = new int[4];
			int[] xywh = new int[4];
			for(int i=0; i<4; i++) {
				rgba[i] = scanner.nextInt();
			}
			color = new Color(rgba[0], rgba[1], rgba[2], rgba[3]);

			for(int i=0; i<4; i++) {
				xywh[i] = (int)scanner.nextDouble();
			}
			rect = new Rectangle(xywh[0], xywh[1], xywh[2], xywh[3]);
		} catch(Exception e) {
			e.printStackTrace();
			color = new Color(200, 50, 100, 200);
			rect = null;
		}


	}

	public void write() {
		try {
			File file = new File("cover.cfg");  
            // if file doesnt exists, then create it  
            if (!file.exists()) {  
                file.createNewFile();  
            }  
            FileWriter fw = new FileWriter(file, false);  
            PrintWriter pw = new PrintWriter(fw);  
			pw.format("%d %d %d %d\n", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
			if (rect == null) {
				pw.println("null");
			} else {
				pw.format("%.2f %.2f %.2f %.2f\n", rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
			}
            fw.flush();  
            fw.close();  
			System.out.println("Cfg saved");
		} catch(Exception e) {
			e.printStackTrace();
		}

	}

	public Color getColor() {
		return color;
	}
	public void setColor(Color c) {
		color = c;
	}

	public Rectangle getRectangle() {
		return rect;
	}
	public void setRectangle(Rectangle r) {
		rect = r;
	}
}
